﻿#include <iostream>
#include <vector>
#include <cmath>
#include <numeric>
using namespace std;
#include <iostream>
// 标准化处理函数
std::vector<double> normalize(const std::vector<double>& data) {
    double maxVal = *std::max_element(data.begin(), data.end());
    std::vector<double> normalizedData;
    for (double val : data) {
        normalizedData.push_back(val / maxVal);
    }
    return normalizedData;
}

// 计算熵值的函数
double calculateEntropy(const std::vector<double>& data) {
    int n = data.size();
    double sum = std::accumulate(data.begin(), data.end(), 0.0);
    double entropy = 0.0;

    // 使用以2为底的对数来计算熵
    for (double val : data) {
        if (val == 0) continue; // 避免对0取对数
        double p = val / sum; // 计算概率
        entropy -= p * log2(p); // 使用log2而不是log
    }
    // 此处不需要除以log(n)，因为熵的单位已经是比特
    return entropy;
}

// 计算权重的函数
std::vector<double> calculateWeight(const std::vector<std::vector<double>>& dataMatrix) {
    int m = dataMatrix.size(); // 指标数量
    int n = dataMatrix[0].size(); // 对象数量
    std::vector<double> weights(m, 0.0);
    std::vector<double> entropyValues(m, 0.0);

    // 计算每个指标的熵值
    for (int i = 0; i < m; ++i) {
        std::vector<double> normalizedData = normalize(dataMatrix[i]);
        entropyValues[i] = calculateEntropy(normalizedData);
    }

    // 计算每个指标的差异系数和权重
    double sumG = 0.0;
    for (int i = 0; i < m; ++i) {
        double g = 1 - entropyValues[i];
        sumG += g;
        weights[i] = g;
    }

    // 归一化权重
    for (int i = 0; i < m; ++i) {
        weights[i] /= sumG;
    }

    return weights;
}

int main() {
    // 假设有13个指标，每个指标对应3个评价对象的数据
    std::vector<std::vector<double>> dataMatrix;
    std::vector<double> vec1; // 第一个一维向量
    std::vector<double> vec2; // 第二个一维向量
    std::vector<double> vec3; // 第三个一维向量

    for (int j = 0; j < 31; j++)
    {
        double p;
        cin >> p;
        vec1.push_back(p);

    };

    for (int j = 0; j < 31; j++)
    {
        double p;
        cin >> p;
        vec2.push_back(p);

    };

    for (int j = 0; j < 31; j++)
    {
        double p;
        cin >> p;
        vec3.push_back(p);

    };
    dataMatrix.push_back(vec1);
    dataMatrix.push_back(vec2);
    dataMatrix.push_back(vec3);



    // 计算权重
    std::vector<double> weights = calculateWeight(dataMatrix);

    // 输出权重
    std::cout << "The weights of the indicators are: " << std::endl;
    for (size_t i = 0; i < weights.size(); ++i) {
        std::cout << "Indicator " << i + 1 << ": " << weights[i] << std::endl;
    }

    return 0;
}


// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件
